package com.ruoyi.web.controller.system;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.WxUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.SMSUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.information.service.IWxUserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 短信验证码服务接口
 */
@RestController
public class SMSCodeController {

    private final RedisCache redisCache;
    private final IWxUserService iWxUserService;

    public SMSCodeController(RedisCache redisCache, IWxUserService iWxUserService) {
        this.redisCache = redisCache;
        this.iWxUserService = iWxUserService;
    }

    /**
     * 发送短信验证码
     * @param phone
     * @return
     */
    @GetMapping("/sendCode")
    public AjaxResult sendCode(String phone){
        // 0、校验手机号
        if(!phone.matches(Constants.PHONE_REGEX)){
            return AjaxResult.error("手机号格式不正确");
        }
        // 1、生成一个6位由 0-9 数字组成的验证码
        String code = generateCode();
        // 2、发送短信验证码
/*        try {
            SMSUtils.sendSMS(phone, code);
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return AjaxResult.error("短信验证码发送失败！");
        }*/
        // 3、把验证码缓存到服务端 - redis ,2 分钟超时
        redisCache.setCacheObject(CacheConstants.SMS_CODE_PRE + phone, code, 2, TimeUnit.MINUTES);

        // 4、响应结果
        return  AjaxResult.success();
    }

    /**
     * 新的绑定手机号方式
     * @param phone
     * @param code
     * @return
     */
    @GetMapping("/sendCodeNew")
    public AjaxResult sendCodeNew(String phone){
        // 0、校验手机号
        if(!phone.matches(Constants.PHONE_REGEX)){
            return AjaxResult.error("手机号格式不正确");
        }
        // 1、从redis中获取验证码
        String codeInRedis = redisCache.getCacheObject(CacheConstants.SMS_CODE_PRE + phone);
        // 2、判断是否存在
        String redisValue = null;
        if(StringUtils.isEmpty(codeInRedis)){
            // 2.1 没查询到
            String code = generateCode();
            redisValue = code + "," + System.currentTimeMillis();
        }else{
            // 2.2 查询到
            String code = codeInRedis.split(",")[0];
            Long lastSendTime = Long.parseLong(codeInRedis.split(",")[1]);
            // 2.2.1 是否过重发时间
            if(System.currentTimeMillis() - lastSendTime <= 30 * 1000){
                return AjaxResult.error("非法请求!");
            }
            // 2.2.1 是、刷新value的时间戳，把发出的时间更新为当前时间
            redisValue = code + "," + System.currentTimeMillis();
        }
        // 3.保存到redis
        redisCache.setCacheObject(CacheConstants.SMS_CODE_PRE + phone, redisValue, 5, TimeUnit.MINUTES);
        // 4.发送短信
        final String code = redisValue.split(",")[0];
        System.out.println("code:"+code);
        new Thread(()->{
            // 异步代码
            try {
                SMSUtils.sendSMS(phone,code);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();

        return  AjaxResult.success();
    }


    /**
     * 生成6位由数字组成的验证码
     * @return
     */
    private String generateCode() {
        String code = "";
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            code += random.nextInt(10); // 随机一个[0-10)的整数
        }
        return code;
    }

    /**
     * 绑定手机号
     * @param phone
     * @param code
     * @return
     */
    @GetMapping("/bindPhone")
    public AjaxResult bindPhone(String phone,String code){
        // 1、根据手机号获取后端缓存的验证码
        String cacheCode = redisCache.getCacheObject(CacheConstants.SMS_CODE_PRE + phone);
        cacheCode = cacheCode.split(",")[0];
        // 2、和前端发送的验证码做比对
        if(StringUtils.isEmpty(cacheCode) || !cacheCode.equals(code)){
            return AjaxResult.error("验证码错误！");
        }
        // 3、比对成功修改当前微信用户的手机号码
        Long userId = SecurityUtils.getLoginUser().getUserId();
        WxUser wxUser = iWxUserService.updatePhoneById(userId,phone);
        return AjaxResult.success().put("userInfo",wxUser);
    }


}
